﻿using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Linq;

namespace BGCOP.CAVTOP.INNERDEFS
{
    public class ManageInners
    {
        public List<Inner> ListaInner;
        public event EventHandler<InnerErrorEventsArgs> ErrInner;
        public bool activa = false;

        public void Inicio()
        {
            ListaInner = new List<Inner>();
        }
        public void AddInner(int numInner)
        {
            string res = "";
            Inner objInner = new Inner();
            objInner.Biometrico = false;
            objInner.Catraca = true;
            objInner.EstadoAtual = Enumeradores.EstadosInner.ESTADO_CONECTAR;
            objInner.Numero = (int)numInner;
            objInner.QtdDigitos = 14;
            objInner.style = "background-color: RED";
            //busqueda del inner
            foreach (Inner inner in ListaInner)
            {
                if (inner.Numero == objInner.Numero)
                {
                    InnerErrorEventsArgs ie = new InnerErrorEventsArgs();
                    ie.MensajeError = "El dispositivo ya se encuentra en el sistema!";
                    ie.SourceError = "inner";
                    if (ErrInner != null )
                        ErrInner(this, ie);
                    return;
                }
            }
            ListaInner.Add(objInner);

        }
        public void ProcesaInner()
        {
            activa = true;
            Thread th = new Thread(new ThreadStart(prcInner));
            th.Start();
        }
        private void prcInner()
        {
            int Ret2 = -1;

           
            EasyInner.DefinirTipoConexao((byte)Enumeradores.TipoConexao.TCP_IP_COM_PORTA_FIXA);
            
            EasyInner.FecharPortaComunicacao();

            Ret2 = EasyInner.AbrirPortaComunicacao(3570);

            if (Ret2 == (int)Enumeradores.Retorno.RET_COMANDO_OK)
            {
                while (activa)
                {
                    foreach (Inner InnerAtual in ListaInner)
                    {
                        //Testa se o Inner deve ir para o Estado de Ping Online. caso não seja Serial..
                        if (InnerAtual.CountPingOnline > 3000 && InnerAtual.EstadoAtual == Enumeradores.EstadosInner.ESTADO_POLLING)
                        {
                            InnerAtual.EstadoAtual = Enumeradores.EstadosInner.PING_ONLINE;
                        }

                        if (InnerAtual.TemporizadorErroComSerial != DateTime.MinValue)
                        {
                            TimeSpan tempo = DateTime.Now - InnerAtual.TemporizadorErroComSerial;

                            //Significa que a mais de 15 segundos esta retornando erro da Serial no método Receber Dados Online..
                            if (tempo.Seconds > 15 || tempo.Minutes > 0)
                            {
                                InnerAtual.EstadoAtual = Enumeradores.EstadosInner.RECONECTANDO_SERIAL;
                            }
                        }

                        //Verifica o Estado do Inner Atual..
                        switch (InnerAtual.EstadoAtual)
                        {
                            case Enumeradores.EstadosInner.ESTADO_CONECTAR:
                                ESTADO_CONECTAR( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_ENVIAR_CFG_OFFLINE:
                                ESTADO_ENVIAR_CFG_OFFLINE( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_COLETAR_BILHETES:
                                ESTADO_COLETAR_BILHETES( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_ENVIAR_CFG_ONLINE:
                                ESTADO_ENVIAR_CFG_ONLINE( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_ENVIAR_DATA_HORA:
                                ESTADO_ENVIAR_DATA_HORA( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_ENVIAR_MSG_PADRAO:
                                ESTADO_ENVIAR_MSG_PADRAO( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_CONFIGURAR_ENTRADAS_ONLINE:
                                ESTADO_CONFIGURAR_ENTRADAS_ONLINE( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_CONFIGURAR_MUDANCAS_ONLINE_OFFLINE:
                                ESTADO_CONFIGURAR_MUDANCAS_ONLINE_OFFLINE( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_POLLING:
                                ESTADO_POLLING( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_ENVIAR_BIPCURTO:
                                ESTADO_ENVIAR_BIPCURTO( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_ENVIAR_MSG_OK:
                                ESTADO_ENVIAR_MSG_OK( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_LIBERA_GIRO_CATRACA:
                                ESTADO_LIBERA_GIRO_CATRACA( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_MONITORA_GIRO_CATRACA:
                                ESTADO_MONITORA_GIRO_CATRACA( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.PING_ONLINE:
                                PING_ONLINE( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.ESTADO_RECONECTAR:
                                ESTADO_RECONECTAR( InnerAtual);
                                break;

                            case Enumeradores.EstadosInner.RECONECTANDO_SERIAL:
                                RECONECTAR_SERIAL( InnerAtual);
                                break;

                        }

                        InnerAtual.CountPingOnline = InnerAtual.CountPingOnline + 100;
                    }
                    //Application.DoEvents();

                    //Realiza Sleep baseado na quantidade de Inners Cadastrados.
                    System.Threading.Thread.Sleep((int)100 / ListaInner.Count);
                }
                EasyInner.FecharPortaComunicacao();
            }
        }

        #region Passos Da Maquina de Estados

        #region ESTADO_CONECTAR
        private static void ESTADO_CONECTAR(  Inner InnerAtual)
        {
            try
            {
                //Declaração de Variáveis..
                int Ret = -1;

                //Zera Variavel de PingOnline
                InnerAtual.CountPingOnline = 0;

                //Exibe Status de Conexão..
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Conectando...";

                //Envia Ping ao Inner..
                Ret = EasyInner.Ping(InnerAtual.Numero);

                //Testa Retorno do Ping..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    //Altera Estado do Inner.
                    //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Conectado";
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_ENVIAR_CFG_OFFLINE;
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_ENVIAR_CFG_OFFLINE
        private static void ESTADO_ENVIAR_CFG_OFFLINE(  Inner InnerAtual)
        {
            try
            {
                //Exibe no rodapé da janela o estado da maquina.
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Enviando Config Offline...";

                //Declaração de Variáveis..
                int Ret = -1;

                //Zera a variável de Ping Online
                InnerAtual.CountPingOnline = 0;

                //Define as configurações do Inner.
                EasyInner.ConfigurarInnerOffLine();
                //EasyInner.DefinirPadraoCartao((byte)UiBIO.cboPadraoCartaoOnline.SelectedIndex);
                EasyInner.DefinirQuantidadeDigitosCartao((byte)InnerAtual.QtdDigitos);
                EasyInner.ReceberDataHoraDadosOnLine((byte)Enumeradores.Opcao.SIM);
                EasyInner.HabilitarTeclado(1, 0);
                //EasyInner.HabilitarTeclado((byte)Enumeradores.Opcao.SIM, 0);

                EasyInner.ConfigurarTipoLeitor((byte)Enumeradores.TipoLeitor.PROXIMIDADE_ABATRACK2);
                //EasyInner.ConfigurarTipoLeitor((byte)Enumeradores.TipoLeitor.MAGNETICO);
                EasyInner.ConfigurarLeitor1((byte)Enumeradores.Operacao.ENTRADA_E_SAIDA);
                EasyInner.ConfigurarLeitor2((byte)Enumeradores.Operacao.ENTRADA_E_SAIDA);
                EasyInner.ConfigurarAcionamento1((byte)Enumeradores.FuncaoAcionamento.ACIONA_REGISTRO_ENTRADA_OU_SAIDA, 5);
                EasyInner.ConfigurarAcionamento2((byte)Enumeradores.FuncaoAcionamento.ACIONA_REGISTRO_ENTRADA_OU_SAIDA, 5);

                //Define Função Default de Sensor Biometria Para Entrada e Saida.
                //EasyInner.DefinirFuncaoDefaultSensorBiometria(10);

                //Envia Configurações para o Inner.
                Ret = EasyInner.EnviarConfiguracoes(InnerAtual.Numero);
                //Ret = 0;

                //Testa retorno do comando de envio de configurações..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_CONFIGURAR_MUDANCAS_ONLINE_OFFLINE;
                    InnerAtual.TempoColeta = (int)EasyInner.RetornarSegundosSys() + 2;
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_COLETAR_BILHETES
        private static void ESTADO_COLETAR_BILHETES(  Inner InnerAtual)
        {
            try
            {
                //Exibe no rodapé da janela o estado da maquina.
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Coletando Bilhetes...";

                //Declaração de Variáveis..
                Bilhete Bilhete;
                Bilhete = new Bilhete();
                Bilhete.Ano = 0;
                Bilhete.Cartao = null;
                Bilhete.Cartao = new StringBuilder();
                Bilhete.Dia = 0;
                Bilhete.Hora = 0;
                Bilhete.Mes = 0;
                Bilhete.Minuto = 0;
                Bilhete.Tipo = 0;

                int Ret = -1;
                string strCartao = "";
                int Count = 0;

                //Zera a contagem de Ping Online.
                InnerAtual.CountPingOnline = 0;
                InnerAtual.CountPingFail = 0;
                InnerAtual.CountRepeatPingOnline = 0;

                //Envia o Comando de Coleta de Bilhetes..
                Ret = EasyInner.ColetarBilhete(InnerAtual.Numero,
                    ref Bilhete.Tipo,
                    ref Bilhete.Dia,
                    ref Bilhete.Mes,
                    ref Bilhete.Ano,
                    ref Bilhete.Hora,
                    ref Bilhete.Minuto,
                    Bilhete.Cartao);

                //Caso exista bilhete a coletar..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    strCartao = "";

                    //Atribui o nro do Cartão..
                    for (Count = 0; Count < 16; Count++)
                    {
                        strCartao += System.Convert.ToString(System.Convert.ToChar(Bilhete.Cartao[Count]));
                    }

                    //Adiciona a lista de bilhetes o Nro bilhete coletado..
                    //UiMainOnline.lstBilhetes.Items.Add("Inner: " +
                        //InnerAtual.Numero + " " +
                        //Bilhete.Tipo + " " +
                        //Bilhete.Dia + "/" +
                        //Bilhete.Mes + "/" +
                        //Bilhete.Ano + " " +
                        //Bilhete.Hora + ":" +
                        //Bilhete.Minuto +
                        //" Cartão: " + strCartao);

                    //Aumenta o tempo de coleta para +15s..
                    InnerAtual.TempoColeta = (int)EasyInner.RetornarSegundosSys() + 2;
                }
                else
                {
                    //Caso tenha passado o tempo de coleta vai para configurações Online.
                    if (EasyInner.RetornarSegundosSys() >= InnerAtual.TempoColeta)
                    {
                        InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_ENVIAR_CFG_ONLINE;
                    }
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_ENVIAR_CFG_ONLINE
        private static void ESTADO_ENVIAR_CFG_ONLINE(  Inner InnerAtual)
        {
            try
            {
                //Exibe estado do Inner no Rodapé da Janela
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Enviando configs Online...";

                //Declaração de Variáveis..
                int Ret = -1;

                //Define Configurações Online..
                EasyInner.ConfigurarInnerOnLine();
                EasyInner.DefinirQuantidadeDigitosCartao((byte)InnerAtual.QtdDigitos);
                EasyInner.ConfigurarTipoLeitor((byte)Enumeradores.TipoLeitor.PROXIMIDADE_ABATRACK2);
                //EasyInner.ConfigurarTipoLeitor((byte)Enumeradores.TipoLeitor.MAGNETICO);
                EasyInner.ReceberDataHoraDadosOnLine((byte)Enumeradores.Opcao.SIM);

                //EasyInner.ConfigurarLeitor1((byte)Enumeradores.Operacao.ENTRADA_E_SAIDA); // Caso o Leitor esteja configurado no Leitor1
                EasyInner.ConfigurarLeitor2((byte)Enumeradores.Operacao.ENTRADA_E_SAIDA);

                EasyInner.ConfigurarAcionamento1((byte)Enumeradores.FuncaoAcionamento.ACIONA_REGISTRO_ENTRADA_OU_SAIDA, 5);
                EasyInner.ConfigurarAcionamento2((byte)Enumeradores.FuncaoAcionamento.ACIONA_REGISTRO_ENTRADA_OU_SAIDA, 5);

                //Envia comando de configurações para o Inner.
                Ret = EasyInner.EnviarConfiguracoes(InnerAtual.Numero);

                //Testa o retorno do Envio de Configurações..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    //Altera Estado para Envio de Data e hora..
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_ENVIAR_DATA_HORA;
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_CONFIGURAR_MUDANCAS_ONLINE_OFFLINE
        private static void ESTADO_CONFIGURAR_MUDANCAS_ONLINE_OFFLINE(  Inner InnerAtual)
        {
            try
            {
                //Exibe estado do Inner no Rodapé da Janela
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Configurando Mudanças Automaticas...";
                int Ret = -1;

                EasyInner.ConfigurarInnerOffLine();

                EasyInner.DefinirEntradasMudancaOnLine((byte)Enumeradores.EntradasMudancaOnline.TECLADO_E_LEITOR1_E_VERI_BIOMETRICA);

                //Se o Inner é Biométrico, configura Mudanças Offline de Biometria..
                if (InnerAtual.Biometrico)
                {
                    EasyInner.DefinirEntradasMudancaOffLineComBiometria((byte)Enumeradores.Opcao.SIM,//Teclado
                                                                        (byte)Enumeradores.Opcao.SIM,//Leitor1
                                                                        (byte)Enumeradores.Opcao.NAO,//Leitor2
                                                                        (byte)Enumeradores.Opcao.SIM,//Verificação
                                                                        (byte)Enumeradores.Opcao.SIM);//Identificação
                }
                else
                {
                    EasyInner.DefinirEntradasMudancaOffLine((byte)Enumeradores.Opcao.SIM, (byte)Enumeradores.Opcao.SIM, (byte)Enumeradores.Opcao.NAO, (byte)Enumeradores.Opcao.NAO);
                }
                EasyInner.DefinirMensagemPadraoMudancaOffLine((byte)Enumeradores.Opcao.SIM, "Modo Offline");
                EasyInner.DefinirMensagemPadraoMudancaOnLine((byte)Enumeradores.Opcao.SIM, "Modo Online");

                //Realiza a configuração de Mudancas automaticas.
                EasyInner.HabilitarMudancaOnLineOffLine((byte)Enumeradores.MudancaOnlineOffline.COM_PING_ONLINE, 8);

                //Envia as configurações de Mundança automatica..
                Ret = EasyInner.EnviarConfiguracoesMudancaAutomaticaOnLineOffLine(InnerAtual.Numero);

                //Testa o retorno do Envio de Configurações..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    //Altera Estado para Envio de Data e hora..
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_COLETAR_BILHETES;
                }
                //UiBIO.lblStatus.Text = "ERRROOOOOOOOOOOOOOOOOOOOO!!!!";
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_ENVIAR_DATA_HORA
        private static void ESTADO_ENVIAR_DATA_HORA(  Inner InnerAtual)
        {
            try
            {
                //Exibe estado do Inner no Rodapé da Janela
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Enviando data e hora...";

                //Declaração de Variáveis..
                int Ret = -1;
                System.DateTime Data;
                Data = System.DateTime.Now;

                //Envia Comando de Relógio ao Inner Atual..
                Ret = EasyInner.EnviarRelogio(
                    InnerAtual.Numero,
                    (byte)Data.Day,
                    (byte)Data.Month,
                    System.Convert.ToByte(Data.Year.ToString().Substring(2, 2)),
                    (byte)Data.Hour,
                    (byte)Data.Minute,
                    (byte)Data.Second);

                //Testa o Retorno do comando de Envio de Relógio..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    //Vai para o passo de Envio de Msg Padrão..
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_ENVIAR_MSG_PADRAO;
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_ENVIAR_MSG_PADRAO
        private static void ESTADO_ENVIAR_MSG_PADRAO(  Inner InnerAtual)
        {
            try
            {
                //Exibe estado do Inner no Rodapé da Janela
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Enviando Mensagem Padrão...";

                //Declaração de Variáveis..
                int Ret = -1;

                //Envia comando definindo a mensagem Padrão Online para o Inner.
                Ret = EasyInner.EnviarMensagemPadraoOnLine(InnerAtual.Numero, (byte)Enumeradores.Opcao.SIM, "Modo Online");

                //Testa o retorno da mensagem enviada..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    //Muda o passo para configuração de entradas Online.
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_CONFIGURAR_ENTRADAS_ONLINE;
                }

            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_CONFIGURAR_ENTRADAS_ONLINE
        private static void ESTADO_CONFIGURAR_ENTRADAS_ONLINE(  Inner InnerAtual)
        {
            try
            {
                //Exibe estado do Inner no Rodapé da Janela
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Configurando Entradas Online...";

                //Declaração de variáveis..
                int Ret = -1;

                //Verifica se o Inner é Biométrico ou não..
                if (InnerAtual.Biometrico)
                {
                    //Habilita entradas com Biometria..
                    Ret = EasyInner.EnviarFormasEntradasOnLine(
                        InnerAtual.Numero,      //Numero do Inner..
                        (byte)InnerAtual.QtdDigitos,  //Qtd Digitos Teclado..
                        1,                      //Eco do Teclado no Display..
                        (byte)Enumeradores.EntradasMudancaOnline.TECLADO_E_LEITOR1_E_VERI_BIOMETRICA,//Teclado + Leitor 1 + Verificação Biométrica..
                        15,                     //Tempo teclado..
                        17);                    //Posição do Cursor no Teclado..
                }
                else  //Caso não fosse um Inner BIO.
                {
                    Ret = EasyInner.EnviarFormasEntradasOnLine(
                        InnerAtual.Numero,      //Numero do Inner..
                        (byte)InnerAtual.QtdDigitos,  //Qtd Digitos Teclado..
                        1,                      //Eco do Teclado no Display..
                        (byte)Enumeradores.EntradasMudancaOnline.TECLADO_LEITOR1_LEITOR2,//Teclado + Leitor1 + Leitor2
                        15,                     //Tempo teclado..
                        17);                    //Posição do Cursor no Teclado..
                }
                //Testa o retorno do comando..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    //Vai para o Estado De Pooling.
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_POLLING;
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_POLLING
        private void ESTADO_POLLING(  Inner InnerAtual)
        {
            try
            {
                //Exibe estado do Inner no Rodapé da Janela
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Estado de Pooling...";

                //Declaração de Variáveis..
                byte Origem = 0;
                byte Complemento = 0;
                StringBuilder Cartao = new StringBuilder();
                byte Dia = 0;
                byte Mes = 0;
                byte Ano = 0;
                byte Hora = 0;
                byte Minuto = 0;
                byte Segundo = 0;
                string strCartao = string.Empty;
                int Ret = -1;
                int Count = 0;

                //Envia o Comando Receber Dados Online..
                Ret = EasyInner.ReceberDadosOnLine(InnerAtual.Numero,
                    ref Origem, ref Complemento, Cartao, ref Dia, ref Mes, ref Ano, ref Hora,
                    ref Minuto, ref Segundo);

                //Atribui Temporizador
                InnerAtual.Temporizador = DateTime.Now;



                //Testa o Retorno do Comando..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {

                    //Teste se a origem é Fim de Acionamento, Função, Anula ou Giro de Catraca..
                    //Caso seja alguma destas origens, retorna para a maquina de estados.
                    if (Complemento == (int)Enumeradores.Origem.FIM_TEMPO_ACIONAMENTO
                        || Complemento == (int)Enumeradores.Origem.GIRO_DA_CATRACA_TOPDATA
                        || Complemento == (int)Enumeradores.Origem.TECLA_FUNCAO
                        || Complemento == (int)Enumeradores.Origem.TECLA_ANULA)
                    {
                        InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_ENVIAR_MSG_PADRAO;
                        return;
                    }

                    InnerAtual.CountPingOnline = 0;

                    //Validar os dados aqui
                    strCartao = "";

                    for (Count = 0; Count < Cartao.Length; Count++)
                    {
                        strCartao += System.Convert.ToString(System.Convert.ToChar(Cartao[Count]));
                    }



                    

                    InnerErrorEventsArgs ie = new InnerErrorEventsArgs();
                    ie.MensajeError = strCartao + " El dispositivo ya se encuentra en el sistema!";
                    ie.SourceError = "inner";
                    if (ErrInner != null)
                        ErrInner(this, ie);
                    return;

                    //UiMainOnline.lstBilhetes.Items.Add("Coleta Online. Inner: " +
                        //InnerAtual.Numero.ToString() + " " +
                        //"Origem: " + Origem.ToString() + " " +
                        //"Complemento: " + Complemento.ToString() +
                        //" Cartão: " + strCartao + " Data: " +
                        //Dia.ToString() + "/" +
                        //Mes.ToString() + "/" +
                        //Ano.ToString() + " " +
                        //Hora.ToString() + ":" +
                        //Minuto.ToString() + ":" +
                        //Segundo.ToString());

                    if (!InnerAtual.Catraca)
                    {
                        InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_ENVIAR_BIPCURTO;

                    }
                    else
                    {
                        //Aciona Bip Curto..
                        EasyInner.AcionarBipCurto(InnerAtual.Numero);

                        //Seleciona o Estado Atual para Envio de Mensagem OK.
                        InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_ENVIAR_MSG_OK;
                    }
                }//Não Existem dados para receber, então ret = a 128
                else if (Ret == 128)
                {
                    //Zera a variável do temporizador de erro de comunicação Serial..
                    InnerAtual.TemporizadorErroComSerial = DateTime.MinValue;
                }
                else
                {
                    //
                    //Se a variável estiver zerada..
                    if (InnerAtual.TemporizadorErroComSerial == DateTime.MinValue)
                    {
                        //Atribui o Datetime.now...
                        InnerAtual.TemporizadorErroComSerial = DateTime.Now;
                    }
                    //Caso não esteja zerada não executa atribuição, pois ja esta realizando a contagem em cada vez que passa pelo inicio da maquina..
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_ENVIAR_BIPCURTO
        private static void ESTADO_ENVIAR_BIPCURTO(  Inner InnerAtual)
        {
            try
            {
                //Exibe estado do Inner no Rodapé da Janela
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Enviando Bip Curto...";

                //Declaração de variáveis..
                int Ret = -1;

                //Envia comando de Acionamento de Bip para o Inner..
                Ret = EasyInner.AcionarBipCurto(InnerAtual.Numero);

                //Testa Retorno do Comando..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    //Vai para o Passo de Exibição de Msg Ok..
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_ENVIAR_MSG_OK;
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_ENVIAR_MSG_OK
        private static void ESTADO_ENVIAR_MSG_OK(  Inner InnerAtual)
        {
            try
            {

                //Exibe estado do Inner no Rodapé da Janela
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Enviando Mensagem OK...";

                //Declaração de Variáveis..
                int Ret = -1;

                //Testa se a Mensagem Temporizada ainda não foi enviada
                if (InnerAtual.FlagMensagemTemporizada == false)
                {
                    //Testa se é uma catraca
                    if (InnerAtual.Catraca)
                    {
                        Ret = EasyInner.EnviarMensagemPadraoOnLine(InnerAtual.Numero, (byte)Enumeradores.Opcao.NAO, "Passe na Catraca");
                        InnerAtual.FlagMensagemTemporizada = true;
                    }
                    else
                    {
                        Ret = EasyInner.EnviarMensagemPadraoOnLine(InnerAtual.Numero, (byte)Enumeradores.Opcao.NAO, "Acesso Liberado");
                        InnerAtual.FlagMensagemTemporizada = true;
                    }

                }
                //Verifica a quantidade de tempo que passou desde a atribuição do Temporizador
                TimeSpan tempo = DateTime.Now - InnerAtual.Temporizador;

                //Verifica se o Inner é ou não uma catraca..
                if (InnerAtual.Catraca)
                {
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_LIBERA_GIRO_CATRACA;

                    //Atualiza flag de Temporizador de mensagem
                    InnerAtual.FlagMensagemTemporizada = false;
                }
                else
                {
                    //Caso Tenha passado de 2 segundos..
                    if (tempo.Seconds > 2)
                    {
                        InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_ENVIAR_MSG_PADRAO;

                        //Atualiza flag de Temporizador de mensagem
                        InnerAtual.FlagMensagemTemporizada = false;
                    }
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_LIBERA_GIRO_CATRACA
        private static void ESTADO_LIBERA_GIRO_CATRACA(  Inner InnerAtual)
        {
            try
            {
                //Exibe estado do Inner no Rodapé da Janela
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Libera Giro da Catraca...";

                //Declaraçaõ de Variáveis..
                int Ret = -1;

                //Envia comando de liberar a catraca para Entrada.
                Ret = EasyInner.LiberarCatracaDoisSentidos(InnerAtual.Numero);

                //Testa Retorno do comando..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_MONITORA_GIRO_CATRACA;
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_MONITORA_GIRO_CATRACA
        private static void ESTADO_MONITORA_GIRO_CATRACA(  Inner InnerAtual)
        {
            try
            {

                //Exibe estado do giro
                //UiMainOnline.lblDados.Text = "Monitorando Giro de Catraca!";


                //Exibe estado do Inner no Rodapé da Janela
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Monitora Giro da Catraca...";

                //Declaração de Variáveis..
                byte Origem = 0;
                byte Complemento = 0;
                StringBuilder Cartao = new StringBuilder();
                byte Dia = 0;
                byte Mes = 0;
                byte Ano = 0;
                byte Hora = 0;
                byte Minuto = 0;
                byte Segundo = 0;
                string strCartao = string.Empty;
                int Ret = -1;

                int a = 1;
                //Zera o contador de Ping Online
                InnerAtual.CountPingOnline = 0;

                //Monitora o giro da catraca..
                Ret = EasyInner.ReceberDadosOnLine(InnerAtual.Numero,
                    ref Origem, ref Complemento, Cartao, ref Dia, ref Mes, ref Ano, ref Hora,
                    ref Minuto, ref Segundo);

                //Testa o retorno do comando..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    //Testa se girou o não a catraca..
                    if (Origem == (int)Enumeradores.Origem.FIM_TEMPO_ACIONAMENTO)
                    {
                        //UiMainOnline.lblDados.Text = "Não girou a catraca!";
                    }
                    else if (Origem == (int)Enumeradores.Origem.GIRO_DA_CATRACA_TOPDATA)
                    {
                        //UiMainOnline.lblDados.Text = "Girou a catraca!";
                    }
                    //Vai para o estado de Envio de Msg Padrão..
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_ENVIAR_MSG_PADRAO;
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region PING_ONLINE
        private static void PING_ONLINE(  Inner InnerAtual)
        {
            try
            {
                //Exibe estado do Inner no Rodapé da Janela
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " PING ONLINE...";

                //Declaração de Variáveis..
                int Ret = -1;

                //Envio ping Online..
                Ret = EasyInner.PingOnLine(InnerAtual.Numero);

                //Testa Retorno do comando..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    //Vai para o Estado de Pooling.
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_POLLING;
                    InnerAtual.CountPingOnline = 0;
                    InnerAtual.CountPingFail = 0;
                }
                else
                {
                    //Incrementa a Variável de Contagem de Ping_Online
                    InnerAtual.CountPingFail++;

                    //Inicializa Variavel de reteste de PingOnline
                    InnerAtual.CountPingOnline = 0;

                    //Vai para o Estado de Pooling
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_POLLING;
                }

                //Envia Pelo menos 3 tentativas de ping Online para o Inner.
                if (InnerAtual.CountPingFail > 2)
                {
                    //Vai para o Estado de reconexão.
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_RECONECTAR;
                    InnerAtual.CountPingOnline = 0;
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region ESTADO_RECONECTAR
        private static void ESTADO_RECONECTAR(  Inner InnerAtual)
        {
            try
            {
                InnerAtual.CountPingOnline = 0;

                //if (UltimoSegundo == DateTime.Now.Second)
                //{
                //    return;
                //}
                //else
                //{
                //    UltimoSegundo = DateTime.Now.Second;
                //}

                //Exibe estado do Inner no Rodapé da Janela
                //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Reconectando...";

                //Declaração de Variáveis..
                int Ret = -1;

                //Envio de Mensagem Temporária..
                Ret = EasyInner.PingOnLine(InnerAtual.Numero);

                //Testa Retorno do comando..
                if (Ret == (int)Enumeradores.Retorno.RET_COMANDO_OK)
                {
                    //Vai para o Estado de Pooling.
                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_CONECTAR;
                    InnerAtual.CountPingOnline = 0;
                }
            }
            catch (Exception ex)
            {
                //MessageBox.Show("Erro:" + ex.Message);
            }
        }
        #endregion

        #region RECONECTAR_SERIAL
        private static void RECONECTAR_SERIAL(  Inner InnerAtual)
        {

            //Exibe estado do Inner no Rodapé da Janela
            //UiMainOnline.lblStatus.Text = "Inner " + InnerAtual.Numero + " Reconectando Serial...";

            //if (UltimoSegundo == DateTime.Now.Second) return;
            //UltimoSegundo = DateTime.Now.Second;

            Thread.Sleep(25);
            InnerAtual.CountRepeatPingOnline += 250;

            if (InnerAtual.CountRepeatPingOnline > 1500)
            {
                //Realiza Ping de DLL.
                int retorno = EasyInner.Ping(InnerAtual.Numero);

                if (retorno == 0)
                {
                    //Zera Variáveis de reconexão..
                    InnerAtual.CountPingFail = 0;
                    InnerAtual.TemporizadorErroComSerial = DateTime.MinValue;

                    //Coloca inner em estado de Configuração.
                    EasyInner.LevantarParaOnLine(InnerAtual.Numero);

                    InnerAtual.EstadoAtual = Enumeradores.EstadosInner.ESTADO_COLETAR_BILHETES;
                    InnerAtual.TempoColeta = (int)EasyInner.RetornarSegundosSys() + 5;
                }
            }
        }

        #endregion

        #endregion

    }
}
